755 words
GTest是谷歌发布的一个跨平台的单元测试框架,主要是为了在不同平台上编写的C++单元测试而生成的 提供了丰富的断言,致命和非致命的判断,参数化 GTest使用简单的宏断言断言分两类 一类是ASSERT系列的,如果当前检测失败则直接退出函数 另一类是EXPECT系列,如果当前点检测失败则继续往下执行 但是必须要在单元测试宏函数中才能使用 是这样用的 12345678910111213141516#include <iostream>#include <gtest/gtest.h>#include "../logs/Xulog.h"TEST(test, great_than){ int age = 20; ASSERT_GT(age, 18); INFO("OK!");}int main(int argc, char* argv[]){ testing::InitGoogleTest(&argc, argv); RUN_ALL_TESTS(); ...
944 words
SQLiteSQLite是一个本地化的数据库,不需要客户端服务端什么的配置,主打就是轻量化方便化 他也不是一个独立的进程,而是可以根据应用程序的需求,可以进行静态或者动态的连接 而且他是直接存储在磁盘文件的,提供了简单易用的API接口 需要注意的是 在SQLite中一个数据库对应了一个数据库文件 常用接口12int sqlite3_threadsafe(); // 查看是否启用线程安全 0-未启用 1-启用 sqlite有三种安全模式 非线程安全模式 线程安全模式(不同的连接在不同的线程是安全的,或者说进程间是安全的,一个句柄不能用于多线程之间) 串行化模式(可以在不同的线程或者进程之间使用同一个句柄) 12int sqlite3_open(const char* filename, sqlite3 **ppDb);int sqlite3_open_v2(const char* filename, sqlite3 **ppDb, int flags, const char* *zVfs); 这里是创建或者打开数据库的两种操作 第一个参数是文件名,第二个参数是传入一个句柄指...
C++
878 words
static是一个非常重要的关键字,为什么呢,用法又多,说不定哪里来一下就给人整懵了,而且还比较复杂,有必要专门记录一下static的用法 static的意思是静态的 一开始在学习C语言时,我们时用它来控制变量和函数的作用域,也就是使用范围,后面学习到进程地址空间,才了解到他也改变了存储的区域 我们知道进程地址空间可以大致分为栈区、堆区、静态区 诶这个静态区是不是眼熟,没错 static修饰的变量都存在静态区,一直到程序结束时才会释放 额外bb一句,所有的常量也存在静态区 简单说,static修饰的对象无非就是变量和函数,但是变量和函数放的位置不一样,static的作用也不一样 C语言中的staticC语言中static一共有三个用法 修饰局部变量->静态局部变量 修饰全局变量->静态全局变量 修饰函数->静态函数 局部变量 在局部变量中static修饰的变量只初始化一次,在之后调用这个函数的时候保留原来的状态 有点类似于全局函数的意思,但是延长了局部变量的生命周期,但是他的作用域还是在函数范围内 修改了他的存储位置,从栈区改到了静态区 如果static变量...
813 words
之前我们虽然学习了数据库的基本操作,但是如果想要了解底层的部分,还是需要理解原理的 为什么要有数据库一开始我们学习时,数据是存储在内存中的,然后慢慢的到了文件 但是如果想要存储成万上亿的数据,内存和文件其实就不太够用了 先不说够不够用,且说增删改查,改和查其实是最麻烦的 不仅仅需要各种循环封装,而且不同语言想要同时使用,就是十分难受的一件事情 主流的数据库有很多,SQL server、Oracle、MySQL、PostgreSQL、SQLite、H2 各有特色,根据需求选择即可 具体安装和设置这里不多赘述 服务器、数据库、表我们在安装数据库时,其实安装了两个部分,客户端mysql和服务端mysqld 所有的数据库操作,其实都是服务端完成的,数据内容也存在服务端里 而客户端只是连接到了服务端,然后发出指令 因此原理上来说,在一个客户端,指定ip和port,就可以连接到对应服务器的mysql 简单使用shell中使用下面的命令登录 1mysql -uroot -p 创建数据库 1create database helloworld; 使用数据库 1use helloworld;...
1.2k words
在之前我们单纯使用muduo实现的时候,并没有考虑到tcp粘包之类的问题,只是进行一个返回 但是在实际应用过程中绝对不能这么草率,需要实现一个应用层协议来解决这些问题 包括序列化和反序列化,粘包 muduo定制的protobuf协议在muduo源文件的example中有实现protobuf的客户端和服务端 我们可以先大致学习一下这里是怎么实现的,然后仿照使用一下 可以看到这里消息回调函数,这里面用的是ProtoBufCodec的onMessage函数 dispatcher是一个分发器,codec_是一个协议处理器 初始化里面是有一个注册消息回调函数,后面会有大用 而在这个类中,我们可以看到onMessage和send,其实就是针对protobuf处理的方法,也就是收到消息之后被调用的方法 在具体看这个onMessage处理函数之前,我们先看这个协议的结构是什么样的 有了这样的协议之后,就可以解决粘包问题 具体的函数调用逻辑是这样的 业务操作逻辑是这样的 proto文件1234567891011121314151617181920syntax = "proto3...
1.9k words
MuduoMuduo是陈硕大佬开发的,一个基于非阻塞IO和事件驱动的C++高并发网络编程库 这是一个基于主从Reactor模型的网络编程库,线程模型是one loop per thread 意思是一个线程只能有一个事件循环(event loop), 用于响应计时器和事件 一个文件描述符只能由一个线程进行读写,也就是一个Tcp连接,必须归属于一个EventLoop管理 基本逻辑是这样的 所谓的主从Reactor就是,在主线程中有一个主Reactor进行事件触发,而在其他其他线程中就是普通的Reactor进行事件触发 在主线程中主要任务就是监控新连接的到来,保证尽可能高效的获取新建连接,再按照负载均衡的方式分发到普通Reactor的线程中,对对应的IO事件进行监控 主从Reactor必然是一个多执行流的并发模式,也就是one thread one loop Server常见接口TcpServer类这个类用来生成服务器对象 ==构造函数是这样的== 1234TcpServer(EventLoop *loop, const In...
1.8k words
poll和epoll都是多路转接的调用,但是epoll实在过于优秀了,一般也都是用epoll的,除此之外还着使用时还蕴含着Reactor设计模式的思想 pollpoll几乎是解决了select的痛点问题的,就像c和c with class一样 使用poll的函数原型和数据结构长这样 123456789#include <poll.h>int poll(struct pollfd *fd, nfds_t nfds, int tiemout);struct pollfd{ int fd; // 文件描述符 short events; // 时间类型 short revents; // 实际发生的时间}; fds:只想一个pollfd结构体数组的指针,每一个结构体都在监视一个文件描述符 nfds:文件描述符的数量 timeout:与select相同,只是直接使用int作为类型,单位是毫秒 epollepoll是为了处理大量句柄而做了改进的poll,在实际中运用的最多的也是这个 系统调用 这个系统调用是用于创建一个epoll模型...
980 words
select多路转接多路转接有三种方案,分别是select,poll和epoll,我们都会讲解和介绍 select的函数原型是这样的 他一共有五个参数,但是可以分为三组 nfds:需要监视的最大的文件描述符值+1 readfds:可读文件描述符集合writefds:可写文件描述符集合exceptfds:异常文件描述符集合 timeout:设置select等待的时间 就绪事件分为三种,可读事件,可写事件,异常事件 timeoutselect可以帮我们同时等待多个文件描述符,但是如果一直轮询多个描述符是不合理的,我们应当可以设置他阻塞或者轮询 因此timeout可以传入三种数据 NULL : 表示没有timeout,select一直阻塞等待,直到有了就绪的文件描述符 0 : 进检测文件描述符集合的状态,然后立即返回,不会进行任何阻塞等待,继续执行后面的逻辑 确定的时间 : 阻塞指定的时间段,没有等到则超时返回 前两个都好理解,第三个的数据类型是timeval,要怎么用呢 他的内部有两个成员,分别对应了秒和微秒 长这样 1234struct timeval { ...